package cn.virens.library.uitls;

import android.graphics.Color;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 * 将Object 转为JSON
 * Created by loioi on 2016/12/15.
 */
public class JsonUtil {
    public static Integer optInteger(JSONObject json, String name) {
        return optInteger(json, name, null);
    }

    public static Integer optInteger(JSONObject json, String name, Integer defaultVal) {
        Object object = optObject(json, name);

        if (object instanceof Float) {
            return (Integer) object;
        } else if (object instanceof Number) {
            return ((Number) object).intValue();
        } else if (object instanceof String) {
            try {
                return Integer.valueOf((String) object);
            } catch (NumberFormatException ignored) {
            }
        }
        return defaultVal;
    }

    public static Long optLong(JSONObject json, String name) {
        return optLong(json, name, null);
    }

    public static Long optLong(JSONObject json, String name, Long defaultVal) {
        Object object = optObject(json, name);

        if (object instanceof Float) {
            return (Long) object;
        } else if (object instanceof Number) {
            return ((Long) object).longValue();
        } else if (object instanceof String) {
            try {
                return Long.valueOf((String) object);
            } catch (NumberFormatException ignored) {
            }
        }
        return defaultVal;
    }

    public static Short optShort(JSONObject json, String name) {
        return optShort(json, name, null);
    }

    public static Short optShort(JSONObject json, String name, Short defaultVal) {
        Object object = optObject(json, name);

        if (object instanceof Float) {
            return (Short) object;
        } else if (object instanceof Number) {
            return ((Short) object).shortValue();
        } else if (object instanceof String) {
            try {
                return Short.valueOf((String) object);
            } catch (NumberFormatException ignored) {
            }
        }
        return defaultVal;
    }

    public static Double optDouble(JSONObject json, String name) {
        return optDouble(json, name, null);
    }

    public static Double optDouble(JSONObject json, String name, Double defaultVal) {
        Object object = optObject(json, name);

        if (object instanceof Double) {
            return (Double) object;
        } else if (object instanceof Number) {
            return ((Number) object).doubleValue();
        } else if (object instanceof String) {
            try {
                return Double.valueOf((String) object);
            } catch (NumberFormatException ignored) {
            }
        }
        return defaultVal;
    }

    public static Float optFloat(JSONObject json, String name) {
        return optFloat(json, name, null);
    }

    public static Float optFloat(JSONObject json, String name, Float defaultVal) {
        Object object = optObject(json, name);

        if (object instanceof Float) {
            return (Float) object;
        } else if (object instanceof Number) {
            return ((Number) object).floatValue();
        } else if (object instanceof String) {
            try {
                return Float.valueOf((String) object);
            } catch (NumberFormatException ignored) {
            }
        }
        return defaultVal;
    }

    public static Boolean optBoolean(JSONObject json, String name) {
        return optBoolean(json, name, null);
    }

    public static Boolean optBoolean(JSONObject json, String name, Boolean defaultVal) {
        Object object = optObject(json, name);

        if (object instanceof Boolean) {
            return (Boolean) object;
        } else if (object instanceof Number) {
            return ((Number) object).intValue() > 0 ? true : false;
        } else if (object instanceof String) {
            return "true".equals(object) || "on".equals(object);
        }
        return defaultVal;
    }


    public static String optBoolean(JSONObject json, String name, String _true, String _false) {
        Boolean _boolean = optBoolean(json, name);
        if (_boolean == null || !_boolean) {
            return _false;
        } else {
            return _true;
        }
    }

    public static Date optDate(JSONObject json, String name) {
        return optDate(json, name, CalendarUtil.YMD);
    }

    public static Date optDate(JSONObject json, String name, String pattern) {
        Object object = json.opt(name);

        if (object instanceof Date) {
            return (Date) object;
        } else if (object instanceof Number) {
            return new Date(((Number) object).longValue());
        } else if (object instanceof String) {
            return CalendarUtil.parse((String) object, pattern);
        }
        return null;
    }

    public static Calendar optCalendar(JSONObject json, String name) {
        Date date = optDate(json, name);
        if (date == null) {
            return null;
        } else {
            return CalendarUtil.clone(date);
        }
    }

    public static String optString(JSONObject json, String name) {
        return optString(json, name, null);
    }

    public static String optString(JSONObject json, String name, String defaultVal) {
        Object object = optObject(json, name);

        if (object != null) {
            return object.toString();
        } else {
            return defaultVal;
        }
    }

    public static JSONObject optJSONObject(JSONObject json, String name) {
        Object object = optObject(json, name);

        if (object instanceof JSONObject) {
            return (JSONObject) object;
        } else if (object instanceof String) {
            try {
                return new JSONObject((String) object);
            } catch (JSONException e) {
            }
        }
        return null;
    }

    public static JSONArray optJSONArray(JSONObject json, String name) {
        Object object = optObject(json, name);

        if (object instanceof JSONArray) {
            return (JSONArray) object;
        } else if (object instanceof String) {
            try {
                return new JSONArray((String) object);
            } catch (JSONException e) {
            }
        }
        return null;
    }

    public static Object optObject(JSONObject json, String name) {
        return json.opt(name);
    }

    public static int optColor(JSONObject json, String name, String defaultVal) {
        return Color.parseColor(optString(json, name, defaultVal));
    }

    public static Spanned optHtml(JSONObject json, String name) {
        String str = optString(json, name);
        if (TextUtils.isEmpty(str)) {
            return null;
        } else {
            return Html.fromHtml(str);
        }
    }

    public static HashMap<String, Object> toMap(JSONObject obj) {
        if (obj == null) return null;

        HashMap<String, Object> result = new HashMap<>();

        Iterator<String> keys = obj.keys();

        while (keys.hasNext()) {
            String key = keys.next();
            Object value = obj.opt(key);

            result.put(key, value);
        }

        return result;
    }

    public static JSONObject toJson(Map<String, Object> map) {
        return new JSONObject(map);
    }
}
